package com.study.newjava8.lambda;

import com.study.newjava8.pojo.Employee;
import org.junit.Test;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Stream的终止操作
 */
public class TestStreamAPI4 {

    List<Employee> employees = Arrays.asList(
            new Employee("huangsm", 22, 40020.0, Employee.Status.BUSY),
            new Employee("huangsm1", 24, 52300.0, Employee.Status.FREE),
            new Employee("huangsm1", 24, 52300.0, Employee.Status.VOCATION),
            new Employee("huangsm1", 24, 52300.0, Employee.Status.VOCATION),
            new Employee("huangsm2", 26, 40100.0, Employee.Status.FREE)
    );

    /**
     * 查询与匹配
     * allMatch-检查是否匹配所有元素
     */
    @Test
    public void test1() {
        boolean b1 = employees.stream()
                .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b1);
    }

    /**
     * anyMatch-检查是否至少匹配一个元素
     */

    @Test
    public void  test2(){
        boolean b = employees.stream()
                .anyMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b);
    }
    /**
     * noneMatch--检查是否没有匹配所有元素
     * findFirst--返回第一个元素
     * findAny--返回当前流中的任意元素
     * count--返回流中元素的总个数
     * max--返回流中的最大值
     * min--返回流中最小值
     */
    @Test
    public void test3()
    {
        Optional<Employee> first = employees.stream()
                .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
                .findFirst();
        System.out.println(first.get());

        Optional<Employee> any = employees.parallelStream()
                .filter(e->e.getStatus().equals(Employee.Status.FREE))
                .findAny();
        System.out.println(any.get());

        long count = employees.stream()
                .count();
        System.out.println(count);

        Optional<Employee> max = employees.stream()
                .max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(max.get());

        //最低工资
        Optional<Double> min = employees.stream()
                .map(Employee::getSalary)
                .min(Double::compareTo);
        System.out.println(min.get());
    }


    /**
     * 归约
     * reduce(T identity,BinaryOperator)/reduce(BinaryOperator)
     * 可以将流中反复结合起来，得到一个值
     */
    @Test
    public void test4(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        //从0+10的总和
        Integer sum = list.stream()
                .reduce(0, (a, n) -> a + n);
        System.out.println(sum);


        //计算当前公司中工资的总和
        Optional<Double> salary = employees.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println(salary.get());
    }

    /**
     * 收集
     * collect--将流转换为其他形式。接收一个Collector接口的实现，用于Stream中元素做汇总方法
     */
    @Test
    public void test5(){
        List<String> collect = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());
        collect.forEach(System.out::println);

        //搜集的数据放到特殊集合中
        HashSet<String> collect1 = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));
    }

    @Test
    public void test6(){
        Long collect = employees.stream()
                .collect(Collectors.counting());
        //总数
        System.out.println(collect);

        Double collect1 = employees.stream()
                .collect(Collectors.averagingDouble((e1) -> e1.getSalary()));
        //工资的平均值
        System.out.println(collect1);

        DoubleSummaryStatistics collect2 = employees.stream()
                .collect(Collectors.summarizingDouble(e -> e.getSalary()));
        //综合
        System.out.println(collect2.getSum());
        //得到工资最小值
        Optional<Double> collect3 = employees.stream()
                .map(Employee::getSalary)
                .collect(Collectors.minBy(Double::compare));
        System.out.println(collect3.get());
    }

    /**
     * 分组
     */
    @Test
    public void test7(){

        Map<Employee.Status, List<Employee>> collect1 = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));
        Map<Employee.Status, List<Employee>> collect = collect1;
        System.out.println(collect1);
    }

    /**
     * 多级分组
     */
    @Test
    public void test8(){
        Map<Employee.Status, Map<String, List<Employee>>> collect = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
                    if (e.getAge() <= 35) {
                        return "青年";
                    } else {
                        return "老年";
                    }
                })));
        System.out.println(collect);
    }
    /**
     * 分区
     */
    @Test
    public void test9(){
        Map<Boolean, List<Employee>> collect = employees.stream()
                .collect(Collectors.partitioningBy(e -> e.getSalary() > 45000));
        System.out.println(collect);
    }

}

